package com.chaomian.generator;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.chaomian.plus.starter.entity.BaseEntity;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * MybatisPlus版代码生成器<br>
 */
public class MybatisPlusCodeGenerator {
    /**
     * 代码生成器
     *
     * @param args
     */
    public static void main(String[] args) {
        //====================配置变量区域=====================//
        String author = "chaomian";
        // 生成的entity、controller、service等包所在的公共上一级包路径全限定名
        String rootPackage = "com.chaomian.plusdemo";
        // 模块名
        String moduleName = "test";

        // 数据库配置
        String mysqlIp = "xxxxx";
        int mysqlPort = 3306;
        String mysqlDataBase = "test";
        String url = String.format("jdbc:mysql://%s:%d/%s?useSSL=false&characterEncoding=utf8", mysqlIp, mysqlPort, mysqlDataBase);
        String username = "root";
        String password = "123456";
        /**表名，多个使用,分隔**/
        String tableNames = "cm_test,cm_haha";
        // 去掉的前缀
        String[] tablePrefix = new String[]{"cm_"};


        // 输出路径 + 定制部分pkg
        String projectPath = System.getProperty("user.dir") + "/code_generator/" + DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss") + "/";
        String javaPath = projectPath + "/src/main/java";
        String modulePath = javaPath + "/" + rootPackage.replace(".", "/") + "/" + moduleName;
        String xmlPath = javaPath + "/xml";
        String other = "model";
        String otherPath = modulePath + "/" + other;
        String mapper = "mapper";
        String mapperPath = modulePath + "/" + mapper;
        String entity = "dao";
        String entityPath = modulePath + "/" + entity;

        //====================生成代码=====================//
        FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.author(author) // 设置作者
                            .disableOpenDir()
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir(javaPath); // 指定输出目录
                })
                .packageConfig(builder -> {
                    // 定制路径
                    HashMap<OutputFile, String> pathInfo = new HashMap<>();
                    pathInfo.put(OutputFile.xml, xmlPath);
                    pathInfo.put(OutputFile.entity, entityPath);
                    pathInfo.put(OutputFile.mapper, mapperPath);
                    pathInfo.put(OutputFile.other, otherPath); // 其他自定义文件路径

                    // 定制包名
                    builder.parent(rootPackage) // 设置父包名
                            .moduleName(moduleName) // 设置父包模块名
                            .entity(entity)
                            .mapper(mapper)
                            .other(other)
                            .pathInfo(pathInfo); // 设置mapperXml生成路径

                })
                .strategyConfig(builder -> {

                    builder.addInclude(tableNames.split(",")) // 设置需要生成的表名
                            .addTablePrefix(tablePrefix);// 设置过滤表前缀

                    builder.entityBuilder()
                            .superClass(BaseEntity.class)
                            .disableSerialVersionUID()
                            .enableChainModel()
                            .enableLombok()
                            .enableRemoveIsPrefix()
                            .enableTableFieldAnnotation()
                            .enableActiveRecord()
                            // 乐观锁
                            .versionColumnName("version")
                            .versionPropertyName("version")
                            .logicDeleteColumnName("deleted")
                            .logicDeletePropertyName("deleted")
                            .naming(NamingStrategy.underline_to_camel)
                            .columnNaming(NamingStrategy.underline_to_camel)
                            .addSuperEntityColumns("id", "created_time", "updated_time")
                            // .addIgnoreColumns("age")
                            .idType(IdType.AUTO)
                            .formatFileName("%sDO");

                    builder.controllerBuilder()
                            // .superClass(BaseController.class)
                            .enableHyphenStyle()
                            .enableRestStyle()
                            .formatFileName("%sController")
                            .build();

                    builder.serviceBuilder()
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl");

                    builder.mapperBuilder()
                            .superClass(BaseMapper.class)
                            .enableMapperAnnotation()
                            .enableBaseResultMap()
                            .enableBaseColumnList()
                            .formatMapperFileName("%sDao")
                            .formatXmlFileName("%sMapper");

                })
                .templateConfig(builder -> {
                    builder.disable()
                            .entityKt("/templates/dto.java")
                            .entity("/templates/entity.java")
                            .service("/templates/service.java")
                            .serviceImpl("/templates/serviceImpl.java")
                            .mapper("/templates/mapper.java")
                            .xml("/templates/mapper.xml")
                            .controller("/templates/controller.java");
                }).injectionConfig(builder -> {
                    // 自定义模板
                    Map<String, String> diyTemplates = new HashMap<>();
                    diyTemplates.put("DTO.java", "/templates/dto.java.vm");
                    diyTemplates.put("Query.java", "/templates/query.java.vm");

                    builder.beforeOutputFile((tableInfo, objectMap) -> {
                                System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
                                // 过滤表前缀
                                String table_name = tableInfo.getName();
                                if (tablePrefix.length > 0) {
                                    for (String s : tablePrefix) {
                                        table_name = StrUtil.removePrefixIgnoreCase(table_name, s);
                                    }
                                }
                                // 自定义变量
                                // 类名 大驼峰
                                String upperClassName = StrUtil.upperFirst(StrUtil.toCamelCase(table_name));
                                objectMap.put("upperClassName", upperClassName);
                                // 对象名 小驼峰
                                objectMap.put("lowerClassName", StrUtil.toCamelCase(table_name));
                            })
                            .customFile(diyTemplates)
                            .build();
                })
                .templateEngine(new TemplateEngineExt())
                .execute();
    }
}
